package com.hotel.BL;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;





import data.POSGuestTable;
import data.POSItem;
import data.POSOrder;
import data.POSTax;
import data.POSorderItem;
import data.passingData.POSEditOrderItem;

public class POSPaymentLogic extends AbstractBL{
	public POSPaymentLogic(HttpServletRequest req,HttpServletResponse resp){
		this.req = req;
		this.resp = resp;
	}
	
	public POSGuestTable setFolioToGuestTable(long posGuestTableId){
		HttpSession session = req.getSession(true);
		long hotelId = 1;
		if (session.getAttribute("hotelId") != null)
			hotelId = (Long) session.getAttribute("hotelId");
		POSgenerateOrderLogic posGLogic = new POSgenerateOrderLogic(req, resp);
		POSGuestTable table = posGLogic.GetPOSGuestTable(posGuestTableId);
		if(table.getDisplayFolioId()==0){
			table.setDisplayFolioId(posGLogic.GetMaxFolioDisplayId(hotelId)+1);
			table = posGLogic.UpdatePOSGuestTable(table);
		}
		
		return table;
	}
	
	private HashMap<String,Object> GetTotalAmountDiscountEachItemFromOrderList(List<POSOrder> orderList,POSEditOrderItem newItem){
		HashMap<String,Object> total = new HashMap<String,Object>();
		long totalitem=0;
		double totalDiscount = 0;
		for(POSOrder order:orderList){
			if(!order.isStatus()) continue;
			if(order.getItem().size()==0) continue;
			POSorderItem orderItem = null;
			for(POSorderItem tmpItem : order.getItem())
				if(tmpItem.getId() == newItem.getCustomId() || (newItem.getItem()!=null && newItem.getItem().equals(tmpItem.getItemString()))){
					orderItem = tmpItem; break;
				}
			if(orderItem==null) continue;
				
			totalDiscount += orderItem.getDiscount();
			totalitem += orderItem.getAmount();
		}
		total.put("totalitem", totalitem);
		total.put("totalDiscount", totalDiscount);
		return total;
	}
	
	private POSorderItem getExistItemInOrder(POSOrder order,POSEditOrderItem newItem){
		POSorderItem orderItem = null;
		for(POSorderItem tmpItem : order.getItem())
			if(tmpItem.getId() == newItem.getCustomId() || (newItem.getItem()!=null && newItem.getItem().equals(tmpItem.getItemString()))){
				orderItem = tmpItem; break;
			}
		return orderItem;
	}

	public void EditPaymentOrderItem(List<POSOrder> orderList,List<POSEditOrderItem> itemList) throws EntityNotFoundException {
		POSgenerateOrderLogic posGLogic = new POSgenerateOrderLogic(req, resp);
		POSTaxLogic posTaxLogic = new POSTaxLogic(req,resp);
		for(POSEditOrderItem newItem:itemList){
			long totalitem=0;
			double totalDiscount = 0;
			boolean changeDiscount = false;
			double avgDiscount = 0;
			
			HashMap<String,Object> totalEachItem = GetTotalAmountDiscountEachItemFromOrderList(orderList,newItem);
			totalitem = (Long) totalEachItem.get("totalitem");
			totalDiscount = (Double) totalEachItem.get("totalDiscount");
			
			if(totalDiscount != newItem.getDiscount() || totalitem != newItem.getA()) {
				changeDiscount = true; avgDiscount = (newItem.getDiscount()==0)? 0 :newItem.getDiscount()/newItem.getA();
			}

			List<POSTax> posTaxList = new ArrayList<POSTax>();
			if(newItem.getItem()==null){
				String[] taxIdList = newItem.getTax().split(",");
				for(String _id:taxIdList)
					posTaxList.add(posTaxLogic.GetPOSTax(Long.parseLong(_id)));
			}
			
			totalitem=0;
			for(POSOrder order:orderList){
				if(!order.isStatus()) continue;
				if(order.getItem().size()==0) continue;
				POSorderItem orderItem = getExistItemInOrder(order,newItem);
				if(orderItem==null) continue;
				
				boolean isupdate = false;
				totalitem += orderItem.getAmount();
				if(totalitem > newItem.getA()){
					long del = totalitem - newItem.getA();
					orderItem.setAmount(orderItem.getAmount()-del);
					totalitem -= del;
					isupdate = true;
				}
				if(newItem.getCustomId()>0 && newItem.getA() != orderItem.getAmount()){
					orderItem.setAmount(newItem.getA());
					totalitem = newItem.getA();
					isupdate = true;
				}
				if(changeDiscount) orderItem.setDiscount(avgDiscount*orderItem.getAmount());
				if(isupdate || changeDiscount){
					if(newItem.getItem()==null)
						orderItem = posGLogic.UpdatePOSCalTax(orderItem,posTaxList);
					else
						orderItem = posGLogic.UpdatePOSCalTax(orderItem);
					orderItem = posGLogic.UpdatePOSOrderItem(orderItem);
				}
			}
			if(totalitem < newItem.getA()){
				int lastindex = orderList.size()-1;
				POSOrder lastestOrder = orderList.get(lastindex);
				while(!lastestOrder.isStatus()){
					lastindex--;
					lastestOrder = orderList.get(lastindex);
				}
				POSorderItem orderItem = getExistItemInOrder(lastestOrder,newItem);
				
				if(orderItem!=null){
					orderItem.setAmount(orderItem.getAmount()+(newItem.getA()-totalitem));
					if(changeDiscount) orderItem.setDiscount(avgDiscount*orderItem.getAmount());
					if(newItem.getItem()==null)
						orderItem = posGLogic.UpdatePOSCalTax(orderItem,posTaxList);
					else
						orderItem = posGLogic.UpdatePOSCalTax(orderItem);
					orderItem = posGLogic.UpdatePOSOrderItem(orderItem);
				}
				else{
					lastestOrder = AddnewEditOrderItemToOrder(lastestOrder,newItem,totalitem,avgDiscount);
				}
			}
		}
	}
	
	private POSOrder AddnewEditOrderItemToOrder(POSOrder order,POSEditOrderItem newItem,long totalItem,double avgDiscount) throws EntityNotFoundException{
		POSItemLogic itemLogic = new POSItemLogic(req, resp);
		POSgenerateOrderLogic posGenOrderLogic = new POSgenerateOrderLogic(req, resp);
		POSTaxLogic posTaxLogic = new POSTaxLogic(req,resp);
		POSorderItem item = new POSorderItem();
		long amount = newItem.getA()-totalItem;
		item.setAmount(amount);
		item.setDiscount(amount * avgDiscount);
		item.setCancel(false);
		item.setStatus(true);
		if(newItem.getItem()!=null){
			POSItem posItem = itemLogic.GetPOSItem(Long.parseLong(newItem.getItem()));
			item.setItem(posItem);
			item.setPrice(posItem.getPrice());
			item.setTitle(posItem.getTitle());

			item = posGenOrderLogic.UpdatePOSCalTax(item);
		}
		else{
			item.setPrice(newItem.getPrice());
			item.setTitle(newItem.getTitle());
			
			String[] taxIdList = newItem.getTax().split(",");
			List<POSTax> posTaxList = new ArrayList<POSTax>();
			for(String _id:taxIdList)
				posTaxList.add(posTaxLogic.GetPOSTax(Long.parseLong(_id)));
			item = posGenOrderLogic.UpdatePOSCalTax(item, posTaxList);
		}
		Key k = datastore.put(item.getEntity());
		
		String itemlist = order.getItemString();
		if(itemlist!=null && itemlist.length()>0)
			itemlist+=",";
		itemlist += k.getId();
		
		order.setItemString(itemlist);
		order = posGenOrderLogic.UpdatePOSOrder(order);
		return order;
	}
}
